package com.xd.clap.services.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xd.clap.commons.Category;
import com.xd.clap.commons.Source;
import com.xd.clap.entity.*;
import com.xd.clap.entity.request.AdviseParam;
import com.xd.clap.entity.request.PageParam;
import com.xd.clap.entity.response.CountResult;
import com.xd.clap.entity.response.Result;
import com.xd.clap.mapper.AdminMapper;
import com.xd.clap.mapper.AdviseMapper;
import com.xd.clap.mapper.ResultMapper;
import com.xd.clap.services.*;
import com.xd.clap.utils.SendMsg;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Supplier;

@Service
public class AdviseServiceImpl implements AdviseService {
    @Resource
    private AdviseMapper am;
    @Resource
    private ResultMapper rm;
    @Resource
    private AdminService ads;
    @Resource
    private AdviseService as;
    @Resource
    private ImageService is;
    @Resource
    private FirstAddressService fs;
    @Resource
    private RateService rs;
    @Resource
    private AdminMapper adminMapper;

    @Override
    public Result uploadAdvise(AdviseParam adviseParam) {
        adviseParam.setCreateTime(new Date());
        boolean isSend = false;
        if (adviseParam.getStateCode() == 0) {
            adviseParam.setState("待分配");
        } else {
            adviseParam.setState("待处理");
        }
        //判断传入的值是否为枚举之一
        Source.fromValue(adviseParam.getSource().getValue());
        Category.fromValue(adviseParam.getCategory().getValue());

        int insert = am.insert(adviseParam);
        if (insert <= 0) {
            return Result.fail(100, "上传失败");
        }
        int aid = adviseParam.getId();
        List<String> imgList = Optional.ofNullable(adviseParam.getImgList()).orElse(Collections.emptyList());

        for (String url : imgList) {
            Image image = new Image();
            image.setUrl(url);
            image.setAid(aid);
            Integer i = is.insertImage(image);
            if (i <= 0) {
                return Result.fail(100, "图片上传失败");
            }
        }
        if (adviseParam.getStateCode() == 1) {
            String phone = getPhoneList(adviseParam);
            isSend = SendMsg.sendMsg(phone);
        }
        return Result.success(isSend, "上传成功");
    }

    private String getPhoneList(AdviseParam adviseParam) {
        List<String> addressList = new ArrayList<>();
        addressList.add(adviseParam.getSecondAddress());
        List<Admin> adminList = ads.getAdminList(addressList);
        List<String> phoneList = new ArrayList<>();
        adminList.forEach(admin -> phoneList.add(admin.getPhone()));
        return String.join(",", phoneList);
    }

    @Override
    public Result getAdvisePage(PageParam pageParam) {
        IPage<Advise> aPage = new Page<>(pageParam.getPage(), pageParam.getPageSize());
        QueryWrapper<Advise> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("create_time");
        //判断用户手机号
        if (!StringUtils.isBlank(pageParam.getPhone())) {
            queryWrapper.eq("phone", pageParam.getPhone());
        }
        //判断一级辖区
        if (!StringUtils.isBlank(pageParam.getFirstAddress())) {
            queryWrapper.eq("first_address", pageParam.getFirstAddress());
        }
        //判断二级辖区
        if (!StringUtils.isBlank(pageParam.getSecondAddress())) {
            queryWrapper.eq("second_address", pageParam.getSecondAddress());
        }
        //判断状态码
        if (pageParam.getStateCode() != null) {
            if (pageParam.getStateCode() == 0 || pageParam.getStateCode() == 3) {
                queryWrapper.eq("state_code", pageParam.getStateCode());
            } else if (pageParam.getStateCode() == 1 || pageParam.getStateCode() == 2) {
                queryWrapper.ge("state_code", 1).le("state_code", 2);
            } else if (pageParam.getStateCode() == 4 || pageParam.getStateCode() == 5) {
                if (pageParam.getIsRate()) {
                    queryWrapper.eq("state_code", pageParam.getStateCode());
                } else {
                    queryWrapper.ge("state_code", 4).le("state_code", 5);
                }
            }
        }
        //判断是否评分
        if (pageParam.getRate() > 0) {
            queryWrapper.gt("rate", 0);
        } else if (pageParam.getRate() == 0) {
            queryWrapper.eq("rate", 0);
        }
        //判断时间类型
        getTime(pageParam, queryWrapper);
        //判断辖区
        if (!StringUtils.isBlank(pageParam.getAddress())) {
            queryWrapper.nested(i -> i.like("first_address", pageParam.getAddress()).or().like("second_address", pageParam.getAddress()));
        }
        //判断问题关键字
        if (!StringUtils.isBlank(pageParam.getKey())) {
            queryWrapper.nested(i -> i.like("first_address", pageParam.getKey()).or().like("second_address", pageParam.getKey()).or().like("content", pageParam.getKey()));
        }
        IPage<Advise> adviseIPage = am.selectPage(aPage, queryWrapper);
        List<Advise> adviseList = adviseIPage.getRecords();
        //查询图片
        for (Advise advise : adviseList) {
            int id = advise.getId();
            List<Image> imgList = is.selectImageByAid(id);
            advise.setImageList(imgList);
        }
        adviseIPage.setRecords(adviseList);
        return Result.success(adviseIPage, "查询成功");
    }

    @Override
    public Result getAdvisePageCode(PageParam pageParam) {
        List<Integer> list = new ArrayList<>();
        if (pageParam.getIsRate()) {
            list.add(getAdviseCode(pageParam, 4, 0));
            list.add(getAdviseCode(pageParam, 4, 1));
        } else {
            list.add(getAdviseCode(pageParam, 0, -1));
            list.add(getAdviseCode(pageParam, 1, -1));
            list.add(getAdviseCode(pageParam, 3, -1));
            list.add(getAdviseCode(pageParam, 4, -1));
        }

        return Result.success(list, "查询成功");
    }

    public Integer getAdviseCode(PageParam pageParam, Integer code, Integer rate) {
        QueryWrapper<Advise> queryWrapper = new QueryWrapper<>();
        //判断一级辖区
        if (!StringUtils.isBlank(pageParam.getFirstAddress())) {
            queryWrapper.eq("first_address", pageParam.getFirstAddress());
        }
        //判断二级辖区
        if (!StringUtils.isBlank(pageParam.getSecondAddress())) {
            queryWrapper.eq("second_address", pageParam.getSecondAddress());
        }
        //判断时间类型
        getTime(pageParam, queryWrapper);
        //判断问题关键字
        if (!StringUtils.isBlank(pageParam.getKey())) {
            queryWrapper.nested(i -> i.like("first_address", pageParam.getKey()).or().like("second_address", pageParam.getKey()).or().like("content", pageParam.getKey()));
        }
        //判断是否评分
        if (rate > 0) {
            queryWrapper.gt("rate", 0);
        } else if (rate == 0) {
            queryWrapper.eq("rate", 0);
        }
        if (code == 0 || code == 3) {
            queryWrapper.eq("state_code", code);
        } else if (code == 1 || code == 2) {
            queryWrapper.ge("state_code", 1).le("state_code", 2);
        } else if (code == 4 || code == 5) {
            if (pageParam.getIsRate()) {
                queryWrapper.eq("state_code", code);
            } else {
                queryWrapper.ge("state_code", 4).le("state_code", 5);
            }
        }
        return am.selectCount(queryWrapper);
    }

    private void getTime(PageParam pageParam, QueryWrapper<Advise> queryWrapper) {
        if (pageParam.getTimeType() != null) {
            Date end = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(end);
            if (pageParam.getTimeType() == 0) {
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                Date start = calendar.getTime();
                queryWrapper.ge("create_time", start);
                queryWrapper.le("create_time", end);
            } else if (pageParam.getTimeType() == 1) {
                calendar.add(Calendar.DAY_OF_MONTH, -3);
                Date start = calendar.getTime();
                queryWrapper.ge("create_time", start);
                queryWrapper.le("create_time", end);
            } else if (pageParam.getTimeType() == 2) {
                calendar.add(Calendar.DAY_OF_MONTH, -7);
                Date start = calendar.getTime();
                queryWrapper.ge("create_time", start);
                queryWrapper.le("create_time", end);
            } else if (pageParam.getTimeType() == 3) {
                calendar.add(Calendar.DAY_OF_MONTH, -30);
                Date start = calendar.getTime();
                queryWrapper.ge("create_time", start);
                queryWrapper.le("create_time", end);
            } else if (pageParam.getTimeType() == 4) {
                calendar.add(Calendar.DAY_OF_MONTH, -183);
                Date start = calendar.getTime();
                queryWrapper.ge("create_time", start);
                queryWrapper.le("create_time", end);
            }
        }
    }

    @Override
    public Result getUrgeAdvise(PageParam pageParam) {
        QueryWrapper<Advise> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("count");
        queryWrapper.orderByAsc("create_time");
        //判断催促次数
        if (pageParam.getCount() == 0) {
            queryWrapper.eq("count", pageParam.getCount());
        } else if (pageParam.getCount() == 1) {
            queryWrapper.ge("count", 1).le("count", 3);
        } else if (pageParam.getCount() == 2) {
            queryWrapper.ge("count", 4).le("count", 5);
        } else if (pageParam.getCount() == 3) {
            queryWrapper.ge("count", 6);
        }
        //判断一级辖区
        if (!StringUtils.isBlank(pageParam.getFirstAddress())) {
            queryWrapper.eq("first_address", pageParam.getFirstAddress());
        }
        //判断二级辖区
        if (!StringUtils.isBlank(pageParam.getSecondAddress())) {
            queryWrapper.eq("second_address", pageParam.getSecondAddress());
        }
        //判断状态码
        queryWrapper.eq("state_code", 1);
        //判断时间类型
        Date end = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(end);
        if (pageParam.getTimeType() == 0) {
            calendar.add(Calendar.DAY_OF_MONTH, -1);
            Date start = calendar.getTime();
            queryWrapper.lt("create_time", start);
        } else if (pageParam.getTimeType() == 1) {
            calendar.add(Calendar.DAY_OF_MONTH, -3);
            Date start = calendar.getTime();
            queryWrapper.lt("create_time", start);
        } else if (pageParam.getTimeType() == 2) {
            calendar.add(Calendar.DAY_OF_MONTH, -7);
            Date start = calendar.getTime();
            queryWrapper.lt("create_time", start);
        } else if (pageParam.getTimeType() == 3) {
            calendar.add(Calendar.DAY_OF_MONTH, -30);
            Date start = calendar.getTime();
            queryWrapper.lt("create_time", start);
        } else if (pageParam.getTimeType() == 4) {
            calendar.add(Calendar.DAY_OF_MONTH, -183);
            Date start = calendar.getTime();
            queryWrapper.lt("create_time", start);
        }
        //判断辖区
        if (!StringUtils.isBlank(pageParam.getAddress())) {
            queryWrapper.nested(i -> i.like("first_address", pageParam.getAddress()).or().like("second_address", pageParam.getAddress()));
        }
        //判断问题关键字
        if (!StringUtils.isBlank(pageParam.getKey())) {
            queryWrapper.like("content", pageParam.getKey());
        }
        List<Advise> adviseList = am.selectList(queryWrapper);
        return Result.success(adviseList, "查询成功");
    }

    @Override
    public Advise getAdviseById(Integer id) {
        Advise advise = am.selectById(id);
        List<Image> imageList = is.selectImageByAid(id);
        advise.setImageList(imageList);
        return advise;
    }

    @Override
    public Result rejectedAdvise(Integer id) {
        Boolean isSet = as.setAdviseStateById(id, 5);
        if (isSet) {
            return Result.success(null, "驳回成功");
        }
        return Result.fail(100, "驳回失败");

    }

    @Override
    public Result sentAddress(AdviseParam adviseParam) {
        UpdateWrapper<Advise> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", adviseParam.getId());
        updateWrapper.set("first_address", adviseParam.getFirstAddress());
        updateWrapper.set("second_address", adviseParam.getSecondAddress());
        Boolean isSet = as.setAdviseStateById(adviseParam.getId(), 1);
        int update = am.update(null, updateWrapper);
        if (isSet && update > 0) {
//            String phone = getPhoneList(adviseParam);
//            boolean isSend = SendMsg.sendMsg(phone);
            List<String> addressList = new ArrayList<>();
            addressList.add(adviseParam.getSecondAddress());
            List<Admin> adminList = ads.getAdminList(addressList);
            List<String> phoneList = new ArrayList<>();
            adminList.forEach(admin -> phoneList.add(admin.getPhone()));
            for(String phone : phoneList){
                QueryWrapper queryWrapper = new QueryWrapper<Admin>()
                        .eq("phone",phone);
                Admin admin = adminMapper.selectOne(queryWrapper);
                if (admin.getOpenId()!=null){
                    Boolean sd = SendMsg.pushMessage(admin.getOpenId());
                }
            }
            return Result.success(null, "分配成功");
        }
        return Result.fail(100, "分配失败");
    }

    @Override
    public Boolean setAdviseStateById(Integer id, Integer stateCode) {
        UpdateWrapper<Advise> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        updateWrapper.set("state_code", stateCode);
        if (stateCode == 1) {
            updateWrapper.set("state", "待处理");
        } else if (stateCode == 2) {
            updateWrapper.set("state", "驳回");
        } else if (stateCode == 3) {
            updateWrapper.set("state", "待审核");
        } else if (stateCode == 4) {
            updateWrapper.set("state", "已通过");
        } else if (stateCode == 5) {
            updateWrapper.set("state", "误报");
        }
        return am.update(null, updateWrapper) > 0;
    }

    @Override
    public Result urgeAdvise(List<Advise> adviseList) {
        List<String> addressList = new ArrayList<>();
        List<Integer> idList = new ArrayList<>();
        adviseList.forEach(item -> {
            addressList.add(item.getSecondAddress());
            idList.add(item.getId());
        });
        List<Admin> adminList = ads.getAdminList(addressList);
        List<String> phoneList = new ArrayList<>();
        adminList.forEach(admin -> {
            if (!phoneList.contains(admin.getPhone())) {
                phoneList.add(admin.getPhone());
            }
        });
        String phone = String.join(",", phoneList);
        boolean isSend = SendMsg.sendUrgeMsg(phone);
        if (isSend) {
            idList.forEach(id -> {
                UpdateWrapper<Advise> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("id", id);
                updateWrapper.setSql("`count`=`count`+1");
                am.update(null, updateWrapper);
            });
            return Result.success(true, "催办成功");
        }
        return Result.fail(0, "催办失败");

    }

    @Override
    public Result getStateCount(String firstAddress) {
        List<CountResult> stateStateList = new ArrayList<>();
        for (int i = 0; i < 6; i++) {
            CountResult stateState = new CountResult();
            QueryWrapper<Advise> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("state_code", i);
            if (!StringUtils.isBlank(firstAddress)) {
                if(firstAddress.equals("湘东镇")){
                    queryWrapper.nested(q -> q.eq("first_address", "湘东镇").or().eq("first_address", "峡山口街"));

                }else{
                    queryWrapper.eq("first_address", firstAddress);
                }

            }
            Integer count = am.selectCount(queryWrapper);
            stateState.setValue(count);
            if (i == 0) {
                stateState.setName("待分配");
            } else if (i == 1) {
                stateState.setName("待处理");
            } else if (i == 2) {
                stateState.setName("驳回");
            } else if (i == 3) {
                stateState.setName("待审核");
            } else if (i == 4) {
                stateState.setName("已完成");
            } else {
                stateState.setName("误报");
            }
            stateStateList.add(stateState);
        }
        return stateStateList.size() == 6 ? Result.success(stateStateList, "查询成功") : Result.fail(0, "查询失败");
    }

    @Override
    public Result getMapRankData() {
        List<FirstAddress> firstAddressList = fs.selectFirstAddressList("");
        List<CountResult> rankList = new ArrayList<>();
        for (int i = 0; i < 11; i++) {
            FirstAddress item = firstAddressList.get(i);
            CountResult rank = new CountResult();
            QueryWrapper<Advise> queryWrapper = new QueryWrapper<>();
            if (item.getAddress().equals("湘东镇")) {
                queryWrapper.eq("first_address", "湘东镇").or().eq("first_address", "峡山口街");
                rank.setName("湘东镇");
                Integer total = am.selectCount(queryWrapper);
                queryWrapper.ge("state_code", 4);
                Integer count = am.selectCount(queryWrapper);
                rank.setValue(total);
                rank.setCount(count);
                rankList.add(rank);
            } else if (!item.getAddress().equals("峡山口街")) {
                queryWrapper.eq("first_address", item.getAddress());
                rank.setName(item.getAddress());
                Integer total = am.selectCount(queryWrapper);
                queryWrapper.ge("state_code", 4);
                Integer count = am.selectCount(queryWrapper);
                rank.setValue(total);
                rank.setCount(count);
                rankList.add(rank);
            }
        }
        return Result.success(rankList, "查询成功");
    }

    @Override
    public Result getAdviseList(String firstAddress) {
        QueryWrapper<Advise> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isBlank(firstAddress)) {
            queryWrapper.eq("first_address", firstAddress);
        }
        queryWrapper.orderByDesc("create_time").last("limit 10");
        List<Advise> adviseList = am.selectList(queryWrapper);
        return Result.success(adviseList, "查询成功");
    }

    @Override
    public Result getLatelyData() {
        List<CountResult> rankList = new ArrayList<>();
        Date now = new Date();
        for (int i = 6; i >= 0; i--) {
            QueryWrapper<Advise> queryWrapper = new QueryWrapper<>();
            CountResult rank = new CountResult();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(now);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.add(Calendar.DAY_OF_MONTH, -i);
            Date start = calendar.getTime();
            calendar.setTime(now);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.add(Calendar.DAY_OF_MONTH, -i + 1);
            Date end = calendar.getTime();
            queryWrapper.ge("create_time", start);
            queryWrapper.le("create_time", end);
            Integer total = am.selectCount(queryWrapper);
            QueryWrapper<Results> query = new QueryWrapper<>();
            query.ge("create_time", start);
            query.le("create_time", end);
            query.isNull("reason");
            Integer count = rm.selectCount(query);
            rank.setValue(total);
            rank.setCount(count);
            rankList.add(rank);
        }
        return Result.success(rankList, "查询成功");
    }

    @Override
    public Result updateRate(Advise advise) {
        UpdateWrapper<Advise> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", advise.getId());
        updateWrapper.set("rate", advise.getRate());
        int update = am.update(null, updateWrapper);
        Rate rate = new Rate();
        rate.setPhone(advise.getPhone());
        rate.setContent("事件奖励");
        rate.setCreateTime(new Date());
        rate.setRate(advise.getRate());
        if (update > 0 && rs.uploadRate(rate)) {
            return Result.success(update, "评分成功");
        }
        return Result.fail(update, "评分失败");
    }

    @Override
    public Result deleteAdvise(Integer adviseId){
        int delete = am.deleteById(adviseId);
        if (delete < 1) {
            return Result.fail(0, "删除失败");
        }

        return Result.success(delete, "删除成功！");
    }

}
